from typing import Dict, List, Optional
from sqlalchemy import or_
from ..models.permission import Permission
from ..models.role_permission import RolePermission
from ..extensions.extensions import db
from datetime import datetime, timezone

class PermissionService:
    @staticmethod
    def get_permission_list(page: int = 1, per_page: int = 10, keyword: Optional[str] = None) -> Dict:
        """
        获取权限列表
        :param page: 页码
        :param per_page: 每页数量
        :param keyword: 搜索关键词
        :return: 权限列表和分页信息
        """
        query = Permission.query.filter_by(deleted=False)
        
        # 关键词搜索
        if keyword:
            query = query.filter(
                or_(
                    Permission.permission_name.like(f'%{keyword}%'),
                    Permission.permission_code.like(f'%{keyword}%'),
                    Permission.description.like(f'%{keyword}%')
                )
            )
        
        # 分页
        pagination = query.order_by(Permission.sort_order.asc(), Permission.created_at.desc()).paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        return {
            'total': pagination.total,
            'page': page,
            'per_page': per_page,
            'items': [item.to_dict() for item in pagination.items]
        }

    @staticmethod
    def get_permission_tree() -> List[Dict]:
        """
        获取权限树形结构
        :return: 权限树形列表
        """
        permissions = Permission.query.filter_by(deleted=False).order_by(
            Permission.sort_order.asc()
        ).all()
        
        def build_tree(parent_id=None):
            tree = []
            for perm in permissions:
                if perm.parent_id == parent_id:
                    node = perm.to_dict()
                    children = build_tree(perm.id)
                    if children:
                        node['children'] = children
                    tree.append(node)
            return tree
        
        return build_tree()

    @staticmethod
    def get_permission_by_id(permission_id: int) -> Optional[Permission]:
        """
        根据ID获取权限
        :param permission_id: 权限ID
        :return: 权限对象
        """
        return Permission.query.filter_by(id=permission_id, deleted=False).first()

    @staticmethod
    def get_permission_by_code(permission_code: str) -> Optional[Permission]:
        """
        根据权限代码获取权限
        :param permission_code: 权限代码
        :return: 权限对象
        """
        return Permission.query.filter_by(permission_code=permission_code, deleted=False).first()

    @staticmethod
    def create_permission(permission_data: Dict) -> Permission:
        """
        创建权限
        :param permission_data: 权限数据
        :return: 权限对象
        """
        permission = Permission(
            permission_name=permission_data['permission_name'],
            permission_code=permission_data['permission_code'],
            description=permission_data.get('description'),
            resource_type=permission_data['resource_type'],
            resource_path=permission_data.get('resource_path'),
            parent_id=permission_data.get('parent_id'),
            sort_order=permission_data.get('sort_order', 0),
            status=permission_data.get('status', True)
        )
        
        db.session.add(permission)
        db.session.commit()
        return permission

    @staticmethod
    def update_permission(permission: Permission, permission_data: Dict) -> Permission:
        """
        更新权限信息
        :param permission: 权限对象
        :param permission_data: 更新的权限数据
        :return: 更新后的权限对象
        """
        for key, value in permission_data.items():
            if hasattr(permission, key):
                setattr(permission, key, value)
        
        permission.updated_at = datetime.now(timezone.utc)
        db.session.commit()
        return permission

    @staticmethod
    def delete_permission(permission: Permission) -> bool:
        """
        删除权限（软删除）
        :param permission: 权限对象
        :return: 是否成功
        """
        # 检查是否有子权限
        if Permission.query.filter_by(parent_id=permission.id, deleted=False).first():
            raise ValueError("存在子权限，无法删除")
        
        permission.deleted = True
        permission.updated_at = datetime.now(timezone.utc)
        db.session.commit()
        return True

    @staticmethod
    def update_permission_status(permission: Permission, status: bool) -> Permission:
        """
        更新权限状态
        :param permission: 权限对象
        :param status: 状态
        :return: 更新后的权限对象
        """
        permission.status = status
        permission.updated_at = datetime.now(timezone.utc)
        db.session.commit()
        return permission 